package gao.xiaolei.controller;

import javax.annotation.Resource;

import gao.xiaolei.dto.*;
import gao.xiaolei.entity.*;
import gao.xiaolei.exception.MyExceptionBase;
import gao.xiaolei.service.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.*;
import gao.xiaolei.annotation.GradeRuleCheck;
import gao.xiaolei.annotation.ProcessTimeCheckAdd;
import gao.xiaolei.annotation.ProcessTimeCheckUpdate;
import gao.xiaolei.exception.ProcessOverTimeException;
import org.springframework.web.multipart.MultipartFile;
import xiaolei.gao.git.MyGitExcepition;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

@RestController
@RequestMapping("/testProject")
public class TestProjectController {

    @Resource(name = "TestProcessService")
    private TestProcessService testProcessService;

    @Resource(name = "GradeRuleService")
    private GradeRuleService gradeRuleService;

    @Resource(name = "TestSystemService")
    private TestSystemService testSystemService;

    @Resource(name = "TestProjectService")
    private TestProjectService testProjectService;

    @Resource(name = "TestCopyService")
    private TestCopyService testCopyService;

    @Resource(name = "AnalysisService")
    private AnalysisService analysisService;

    @Resource(name = "TestBugService")
    private TestBugService testBugService;

    @PostMapping("")
    public void addTestProject(@RequestBody TestProject testProject) throws MyGitExcepition {
        testProjectService.addTestProject(testProject);
    }

    @PutMapping("")
    public void updateTestProject(@RequestBody TestProject testProject) {
        testProjectService.updateTestProject(testProject);
    }

    @PutMapping("/delList")
    public void deleteTestProjectList(@RequestParam("ids") List<String> ids) {
        testProjectService.deleteTestProjectList(ids);
    }

    @DeleteMapping("/{id}")
    public void deleteTestProject(@PathVariable("id") String id) {
        testProjectService.deleteTestProject(id);
    }

    @DeleteMapping("/group/{groupId}")
    public void deleteTestProjectByGroup(@PathVariable("groupId") String groupId) {
        testProjectService.deleteTestProjectByGroup(groupId);
    }

    @GetMapping("/count/group/{groupId}")
    public Integer getProjectCountByGroupId(@PathVariable("groupId") String groupId) {
        return testProjectService.getCountByGroupId(groupId);
    }

    @GetMapping("/group/{groupId}")
    //根据组Id获取项目列表（树形列表）
    public List<TestTreeDto> getProjectListByGroupId(@PathVariable("groupId") String groupId) {
        return testProjectService.findProjectListByGroupId(groupId);
    }

    @GetMapping("/group/auth/{groupId}")
    //根据组Id获取项目列表（供生成access_token使用的）
    public List<String> getProjectListByGroupIdForAuth(@PathVariable("groupId") String groupId) {
        return testProjectService.findProjectListByGroupIdForAuth(groupId);
    }

    @GetMapping("/rootFolder/{projectId}")
    //获取项目下面复制的测试需求、测试计划、测试执行文件夹和测试分析和bug分析(树形列表)
    public List<TestTreeDto> getProjectDownCopyFolder(@PathVariable("projectId") String projectId) {
        return testCopyService.getCopyFolder(projectId);
    }

    @GetMapping("/rootFolder/rootItem/{projectId}/{type}/{parentId}")
    //获取项目下面复制的测试需求、测试计划、测试执行文件夹下面的最顶端节点（树形列表）
    public List<TestTreeDto> getCopyFolderDownRootItem(@PathVariable("projectId") String projectId,
                                                       @PathVariable("type") int type,
                                                       @PathVariable("parentId") String parentId) {
        return testCopyService.getRootItemList(projectId, type, parentId);
    }

    @GetMapping("/childrenItem/{type}/{id}")
    //获取项目下面复制的测试需求、测试计划、测试执行、测试报告文件夹下面的某个节点(除了最顶端节点)的子节点列表（树形列表）
    public List<TestTreeDto> getCopyFolderDownRootItem(@PathVariable("type") int type,
                                                       @PathVariable("id") String id) {
        return testCopyService.geChildrenItemList(id, type);
    }

    @GetMapping("/all")
    public List<TestProjectOutDto> getAllTestProject() {
        return testProjectService.findAllTestProject();
    }

    @GetMapping("/groupList/leadingCadre/{leadingCadre}")
    public List<GroupDto> getGroupListByLeadingCadre(@PathVariable("leadingCadre") String leadingCadre) {
        return testProjectService.getGroupByLeadingCadre(leadingCadre);
    }

    //获取该负责人负责的所有测试项目
    @GetMapping("/all/leadingCadre/{leadingCadre}")
    public List<TestProjectOutDto> getAllTestProjectByLeadingCadre(@PathVariable("leadingCadre") String leadingCadre) {
        return testProjectService.findAllTestProjectByLeadingCadre(leadingCadre);
    }

    @GetMapping("/detail/{id}")
    public TestProjectOutDto getTestProjectDetail(@PathVariable("id") String id) {
        return testProjectService.getDetail(id);
    }

    @GetMapping("/system/detail/{projectId}")
    public TestSystemDto getSystemOfProjectDetail(@PathVariable("projectId") String projectId) {
        return testSystemService.getSystemDetailOfProject(projectId);
    }

    @GetMapping("/testProcess/{projectId}")
    public TestProcess getTestProcess(@PathVariable("projectId") String projectId) {
        return testProcessService.getTestProcessByProject(projectId);
    }

    @GetMapping("/testProcess/isOver/{projectId}")
    public Integer getTestProcessIsOver(@PathVariable("projectId") String projectId) {
        return testProcessService.getTestProcessIsOver(projectId) ? 1 : 0;
    }

    @PostMapping("/testProcess")
    @ProcessTimeCheckAdd
    public void addTestProcess(@RequestBody TestProcess testProcess) {
        testProcessService.addProcess(testProcess);
    }

    @PutMapping("/testProcess")
    @ProcessTimeCheckUpdate
    public void updateTestProcess(@RequestBody TestProcess testProcess) {
        testProcessService.updateProcess(testProcess);
    }

    @GetMapping("/gradeRule/{projectId}")
    public GradeRule getGradeRule(@PathVariable("projectId") String projectId) {
        return gradeRuleService.getGradeRuleByProject(projectId);
    }

    @PostMapping("/gradeRule")
    @GradeRuleCheck
    public void addGradeRule(@RequestBody GradeRule gradeRule) {
        gradeRuleService.addGradeRule(gradeRule);
    }

    @PutMapping("/gradeRule")
    @GradeRuleCheck
    public void updateGradeRule(@RequestBody GradeRule gradeRule) {
        gradeRuleService.updateGradeRule(gradeRule);
    }

    @PostMapping("/automaticSettleGrade")
    public void automaticSettleGrade(@RequestParam("projectId") String projectId) {
        gradeRuleService.automaticSettleGrade(projectId);
    }

    @PostMapping("/manualSettleGrade")
    public void manualSettleGrade(@RequestBody TestPersonalGrade testPersonalGrade) {
        gradeRuleService.manualSettleGrade(testPersonalGrade);
    }

    @PostMapping("/noticeGradePublic")
    //老师通知组员项目的成绩出来了
    public void noticeUserInProjectGradePublic(@RequestParam("projectId") String projectId,
                                               @RequestParam("userId") String userId) {
        testProjectService.noticeUserInProjectGradePublic(projectId, userId);
    }

    @GetMapping("/classes/group/project/grade/{classesId}/{userId}")
    //获取用户在某个班级下每个组的每个项目的成绩信息
    public List<GradeOutDto> getClassesMemberGradeInWitchProject(@PathVariable("classesId") String classesId,
                                                                 @PathVariable("userId") String userId) {
        return testProjectService.getClassesMemberGradeInWitchProject(classesId, userId);
    }

    @GetMapping("/group/project/grade/{groupId}/{userId}")
    //获取用户在某个组下每个项目的成绩信息
    public List<GradeOutDto> getGroupMemberGradeInWitchProject(@PathVariable("groupId") String groupId,
                                                               @PathVariable("userId") String userId) {
        return testProjectService.getGroupMemberGradeInWitchProject(groupId, userId);
    }

    @GetMapping("/grade/{projectId}/{userId}")
    //获取用户某个项目的成绩信息
    public List<GradeOutDto> getUserGradeInWitchProject(@PathVariable("projectId") String projectId,
                                                        @PathVariable("userId") String userId) {
        return testProjectService.getUserGradeInWitchProjectForUser(userId, projectId);
    }

    @GetMapping("/copyTrqDetail/{id}")
    //获取某个复制测试需求的详细信息
    public TrqCopyOutDto getCopyTrqDetail(@PathVariable("id") String id) {
        return testCopyService.getCopyTrqDetail(id);
    }

    @GetMapping("/copyTrqCheckLog/{id}")
    //获取某个复制测试需求的审核记录
    public List<TestCheckLogDto> getCopyTrqCheckLog(@PathVariable("id") String id) {
        return testCopyService.getCopyTrqCheckLog(id);
    }

    @GetMapping("/copyTrqCheckLogAnnotate/{id}")
    //获取某个复制测试需求的审核记录的批注
    public String getCopyTrqCheckLogAnnotate(@PathVariable("id") String id) {
        return testCopyService.getCopyTrqCheckLogAnnotate(id);
    }

    @GetMapping("/copyDesignDetail/{id}")
    //获取某个复制测试计划的详细信息
    public TestDesignOutDto getCopyDesignDetail(@PathVariable("id") String id) {
        return testCopyService.getCopyDesignDetail(id);
    }

    @GetMapping("/copyDesignCheckLog/{id}")
    //获取某个复制测试执计划的审核记录
    public List<TestCheckLogDto> getCopyDesignCheckLog(@PathVariable("id") String id) {
        return testCopyService.getCopyDesignCheckLog(id);
    }

    @GetMapping("/copyDesignCheckLogAnnotate/{id}")
    //获取某个复制测试计划的审核记录的批注
    public String getCopyDesignCheckLogAnnotate(@PathVariable("id") String id) {
        return testCopyService.getCopyDesignCheckLogAnnotate(id);
    }

    @GetMapping("/copyRunDetail/{id}")
    //获取某个复制测试执行的详细信息
    public TestRunOutDto getCopyRunDetail(@PathVariable("id") String id) {
        return testCopyService.getCopyRunDetail(id);
    }

    @GetMapping("/copyRunCheckLog/{id}")
    //获取某个复制测试执行的审核记录
    public List<TestCheckLogDto> getRunTrqCheckLog(@PathVariable("id") String id) {
        return testCopyService.getRunCopyCheckLog(id);
    }

    @GetMapping("/copyRunCheckLogAnnotate/{id}")
    //获取某个复制测试执行的审核记录的批注
    public String getCopyRunCheckLogAnnotate(@PathVariable("id") String id) {
        return testCopyService.getCopyRunCheckLogAnnotate(id);
    }

    @PutMapping("/grade/CopyItems")
    //给复制的测试需求、计划、执行打分
    public void gradeCopyItem(@RequestParam("id") String id,
                              @RequestParam("type") int type,
                              @RequestParam("grade") int grade,
                              @RequestParam("judge") String judge) {
        testCopyService.gradeCopyItem(type, id, grade, judge);
    }

    @PutMapping("/grade/bug")
    //给bug打分
    public void gradeBug(@RequestParam("id") String id,
                         @RequestParam("grade") int grade) {
        testBugService.gradeBug(id, grade);
    }

    //查找到该用户所属的项目以供用户选择某个项目进入
    @GetMapping("/common/userIn/{userId}")
    public List<TestProjectOutDto> getUserWitchProjectCanInto(@PathVariable("userId") String userId) {
        return testProjectService.getUserWitchProjectCanInto(userId);
    }

    //获取测试项目的分析结果
    @GetMapping("/analysis/{projectId}/{parentId}")
    public AnalysisOutDto getTreeAnalysis(@PathVariable("projectId") String projectId,
                                          @PathVariable("parentId") String parentId) {
        return analysisService.getAnalysisByParentId(projectId, parentId);
    }

    //添加项目bug
    @PostMapping("/bug")
    public TestBug addTestBug(@RequestParam("id") String id,
                              @RequestParam("toTrq") String toTrq,
                              @RequestParam("title") String title,
                              @RequestParam("author") String author,
                              @RequestParam("projectId") String projectId,
                              @RequestParam("describe") String describe,
                              @RequestParam("attachedFiles") MultipartFile[] attachedFiles) throws IOException {
        return testBugService.addTestBug(id, toTrq, title, author, projectId, describe, attachedFiles);
    }

    //修改项目bug
    @PutMapping("/bug")
    public TestBug updateTestBug(@RequestParam("id") String id,
                                 @RequestParam("toTrq") String toTrq,
                                 @RequestParam("title") String title,
                                 @RequestParam("author") String author,
                                 @RequestParam("projectId") String projectId,
                                 @RequestParam("describe") String describe,
                                 @RequestParam(name = "newAttachedIds", required = false) List<String> newAttachedIds,
                                 @RequestParam("attachedFiles") MultipartFile[] attachedFiles,
                                 @RequestParam("currentUserId") String currentUserId) throws IOException {
        return testBugService.updateTestBug(id, toTrq, title, author, projectId, describe, newAttachedIds, attachedFiles, currentUserId);
    }

    //获取项目bug列表
    @GetMapping("/bug/list/{projectId}")
    public List<TestBug> getBugList(@PathVariable("projectId") String projectId) {
        return testBugService.getBugListBuProjectId(projectId);
    }

    //获取项目bug详情
    @GetMapping("/bug/detail/{id}")
    public BugOutDto getBugDetail(@PathVariable("id") String id) {
        return testBugService.getBugDetail(id);
    }

    //删除项目bug
    @PutMapping("/bug/del/{currentUserId}")
    public void deleteBug(@RequestBody List<String> ids,
                          @PathVariable("currentUserId") String currentUserId) {
        testBugService.deleteBug(ids, currentUserId);
    }

    //下载项目bug附件
    @GetMapping("/bug/attach/{attachedId}")
    public ResponseEntity<byte[]> deleteBug(@PathVariable("attachedId") String attachedId) throws UnsupportedEncodingException {
        return testBugService.downloadAttached(attachedId);
    }


    @ExceptionHandler(Exception.class)
    public ResponseEntity<ResponseEnvelope<String>> handelError(Exception e) {
        e.printStackTrace();
        Integer code = null;
        if (e.getClass() == MissingServletRequestParameterException.class)
            code = 400;
        else if (e instanceof MyExceptionBase)
            code = 407;
        else
            code = 500;
        ResponseEnvelope<String> result = new ResponseEnvelope<String>(code, e.getMessage(), null);
        return new ResponseEntity<ResponseEnvelope<String>>(result, HttpStatus.valueOf(500));
    }

}
